package jp.ac.u_tokyo.dch.action.data;

import java.io.File;
import java.io.IOException;

import jp.ac.u_tokyo.dch.util.DchCommonUtil;
import jp.ac.u_tokyo.dch.view.Constants;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.xwork.StringUtils;
import org.apache.log4j.Logger;

import com.opensymphony.xwork2.ActionSupport;
/**
* ファイルアップロードを担当
* @version 1.1
*
*/
public class FileUploadAction extends ActionSupport {

	/**
	 *シリアル番号
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * ログ
	 */
	protected Logger logger = Logger.getLogger(getClass());

	/**
	 * アップロードファイル情報
	 */
	private File upload;
	/**
	 * コンテンツタイプ
	 */
	private String uploadContentType;
	/**
	 * アップロードファイル名
	 */
	private String uploadFileName;
	/**
	 * ファイル名
	 */
	private String fileName;
	/**
	 * サムネイル
	 */
	private String thumbNail;
	/**
	 * ファイルタイプ（０：イメージ、１：画像）
	 */
	private String fileType;

	/**
	 * 物理ファイル名
	 */
	private String realFileName;

	/**
	 * 初期化処理を行う
	 * @return 結果
	 */
	public String init() {
		return SUCCESS;
	}

	/**
	 * ファイルアップロード処理を行う
	 * @return 結果
	 */
	public String doUpload() {

		if (upload == null) {
			addFieldError("uploadFile", "ファイルを選択してください。");
			return ERROR;
		}

		if (StringUtils.isEmpty(fileName)) {
			addFieldError("uploadFile", "ファイル名を入力してください。");
			return ERROR;
		}

		logger.info("absolutePath:"+ upload.getAbsolutePath());
		logger.info("attachFileContentType:"+ uploadContentType);
		logger.info("attachFileFileName:"+ uploadFileName);

		String tempFileName = String.valueOf(System.currentTimeMillis());
		try {
			//ファイルの拡張子
			String extensionName = FilenameUtils.getExtension(uploadFileName);

			//ファイル形式チェック
			if (!isAcceptExt(extensionName)) {
				addActionError("有効なファイル形式ではありません。");
				return ERROR;
			}
			FileUtils.copyFile(upload, new File(getUploadPath() + tempFileName+"." + extensionName));

			logger.info("UploadFileFileName completed :"+ tempFileName);

			if (isImgContentType(extensionName)) {
				//画像変換コマンド
				String imageMagickExe = getText("imageMagickExe");
				//変換後のファイル名
				realFileName = tempFileName+".jpg";
				//変換元ファイル経路
				String inputFile = getUploadPath() + tempFileName + "." + extensionName;
				//変換後ファイル経路
				String outputFile = getUploadPath() + realFileName;
				//イメージ変換
				int result = DchCommonUtil.execImageConvert(imageMagickExe,inputFile,outputFile,null);
				if(result < 0){
					addActionError("ファイル変換エラー");
					return ERROR;
				}
				//サムネイルサイズ
				String thumbSize = getText("thumbSize");
				//サムネイルファイル名
				thumbNail = DchCommonUtil.THUMNBNAIL_PREFIX + tempFileName + ".jpg";
				//変換されたファイルを設定
				inputFile = outputFile;
				//サムネイルファイル経路
				outputFile = getUploadPath()+thumbNail;
				//サムネイル作成を行う
				result = DchCommonUtil.execImageConvert(imageMagickExe,inputFile,outputFile,thumbSize);
				if(result < 0){
					addActionError("ファイル変換エラー");
					return ERROR;
				}

				fileType = Constants.FILE_TYPE_IMAGE;

			} else if (isVideoContenType(extensionName)){

				//動画からThumNail画像を作成
				String fileSource = getUploadPath() + tempFileName + "." + extensionName;
				String destination = getUploadPath();
				String ffmpegExe =getText("ffmpegExeDir");
				//FLVファイルに変換
				//flvSrc = DchCommonUtil.makeViedoConvert(ffmpegExe,fileSource, destination, thumbFileName);
				String flvSrc = DchCommonUtil.makeViedoConvert(ffmpegExe,fileSource, destination, tempFileName);

				if (!"error".equals(flvSrc)) {
					String thumbSize = getText("thumbSize");
					String thumbOutCnt = getText("thumbOutCnt");
					String flvtool2 = getText("flvtool2");
					//サムネイル画像を作成
					thumbNail = DchCommonUtil.makeViedoThumbnail(ffmpegExe,fileSource, destination, tempFileName, thumbSize, thumbOutCnt);

					//FLVファイルにメータ情報を書き込む
					DchCommonUtil.exeFlvToos(flvtool2, getUploadPath()+flvSrc);
					realFileName = flvSrc;
					fileType = Constants.FILE_TYPE_VIDEO;
				} else {
					addActionError("ファイル変換エラー");
					return ERROR;
				}

			} else {
				addActionError("有効なファイル形式ではありません。");
				return ERROR;
			}

		} catch (IOException e) {
			logger.error(e.getMessage());
			addActionError("ファイル変換エラー");
			return ERROR;
		}

		return SUCCESS;
	}
	/**
	 * アップロードファイルを返す
	 * @return アップロードファイル
	 */
	public File getUpload() {
		return upload;
	}
	/**
	 * アップロードファイルをセットする
	 * @param アップロードファイル
	 */
	public void setUpload(File upload) {
		this.upload = upload;
	}
	/**
	 * アップロードコンテンツタイプを返す
	 * @return アップロードコンテンツタイプ
	 */
	public String getUploadContentType() {
		return uploadContentType;
	}
	/**
	 * アップロードコンテンツタイプをセットする
	 * @param アップロードコンテンツタイプ
	 */
	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	/**
	 * アップロードファイル名を返す
	 * @return アップロードファイル名
	 */
	public String getUploadFileName() {
		return uploadFileName;
	}
	/**
	 * アップロードファイル名をセットする
	 * @param アップロードファイル名
	 */
	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	/**
	 * 変換したファイル名を返す
	 * @return 変換したファイル名
	 */
	public String getRealFileName() {
		return realFileName;
	}
	/**
	 * 変換したファイル名をセットする
	 * @param 変換したファイル名
	 */
	public void setRealFileName(String realFileName) {
		this.realFileName = realFileName;
	}
	/**
	 * 画面から入力されたファイル名を返す
	 * @return 画面から入力されたファイル名
	 */
	public String getFileName() {
		return fileName;
	}
	/**
	 * 画面から入力されたファイル名をセットする
	 * @param 画面から入力されたファイル名
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	/**
	 * サムネイルファイルを返す
	 * @return サムネイル
	 */
	public String getThumbNail() {
		return thumbNail;
	}
	/**
	 * サムネイルをセットする
	 * @param サムネイル
	 */
	public void setThumbNail(String thumbNail) {
		this.thumbNail = thumbNail;
	}

	/**
	 *ファイルタイプを返す
	 * @return ファイルタイプ
	 */
	public String getFileType() {
		return fileType;
	}
	/**
	 *ファイルタイプをセットする
	 * @param ファイルタイプ
	 */
	public void setFileType(String fileType) {
		this.fileType = fileType;
	}
	/**
	 * アップロードファイルの保存先を求める
	 * @return 物理的保存先
	 */
	private String getUploadPath() {
		String uploadPath =   getText("uploadFileDir");
		uploadPath = uploadPath.replace("\\", "/").replace("//", "/");
		logger.info("getUploadPath() uploadPath:"+uploadPath);
		return uploadPath;
	}

	/**
	 * ファイル形式チェック
	 * @param extensionName 拡張子
	 * @return true:受入、false:受入しない
	 */
	private boolean isAcceptExt(String extensionName) {

		//有効なファイルタイプリストを取得
		String imgContentType = getText("imgContentType");
		String videoContenType = getText("videoContentType");

		return StringUtils.contains(imgContentType, extensionName.toLowerCase())
				|| StringUtils.contains(videoContenType, extensionName.toLowerCase());
	}

	/**
	 * イメージファイルかをチェックする
	 * @param extensionName 拡張子
	 * @return true:イメージファイル、false:イメージファイルではない
	 */
	private boolean isImgContentType(String extensionName) {

		String imgContentType = getText("imgContentType");

		return StringUtils.contains(imgContentType, extensionName.toLowerCase());
	}
	/**
	 * 画像ファイルかをチェックする
	 * @param extensionName 拡張子
	 * @return true:画像ファイル、false:画像ファイルではない
	 */
	private boolean isVideoContenType(String extensionName) {

		String videoContenType = getText("videoContentType");

		return StringUtils.contains(videoContenType, extensionName.toLowerCase());
	}


}
